﻿using System;
using System.Collections.Generic;
using System.Text;
using ExpressionUtil.Common;

namespace ExpressionUtil.Parser
{
    /// <summary>
    /// 创建节点的委托
    /// </summary>
    /// <param name="context"></param>
    internal delegate void CreateNodeHandler(ParseContext context);

    /// <summary>
    /// 表达式解析器
    /// </summary>
    internal class ExpressionParser
    {
        /// <summary>
        /// 解析参数
        /// </summary>
        private ParseContext context;

        /// <summary>
        /// 第一个解析处理程序
        /// </summary>
        private IParseHandler first;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        /// <param name="exp">需要解析的表达式字符串</param>
        public ExpressionParser(string exp)
        {
            this.context = new ParseContext(exp);
            this.first = new Handler.BracketFunctionHandler();
        }

        /// <summary>
        /// 解析出来的变量节点集合
        /// </summary>
        public Dictionary<string, Node.VariableNode> Variables
        {
            get
            {
                return this.context.Variables;
            }
        }

        /// <summary>
        /// 解析方法
        /// </summary>
        /// <returns>解析出来的语法树的根节点</returns>
        public Node.Common.Node Parse()
        {
            while (this.context.Scanner.MoveToNextElement())
            {
                this.ParseCore(this.context.Scanner.CurrentElement);
            }
            this.ParseCore(this.context.Scanner.CurrentElement);
            this.ParseLastOperatorStackElement();
            if (this.context.PostfixStack.Count > 1)
            {
                throw new FormatException("Missing operator.");
            }
            else if (this.context.PostfixStack.Count == 0)
            {
                throw new FormatException("There isn't valide element in this expression.");
            }
            return this.context.PostfixStack.Pop();
        }

        /// <summary>
        /// 解析单词
        /// </summary>
        /// <param name="element">需要解析的单词</param>
        private void ParseCore(string element)
        {
            this.first.ParseElement(element, this.context);
        }

        /// <summary>
        /// 解析堆栈中的剩余单词
        /// </summary>
        private void ParseLastOperatorStackElement()
        {
            while (this.context.OperatorStack.Count > 0)
            {
                string op = this.context.OperatorStack.Pop();
                if (op.EndsWith("("))
                {
                    throw new FormatException("Missing right bracket.");
                }
                CheckHelper.CreateHandlerExists(op, "Unknow operator.");
                ParseContext.CreateHandlerMap[op](this.context);
            }
        }
    }
}